package io.xxx.omni.osc.sync

import com.alibaba.fastjson.JSONObject
import io.xxx.omni.osc.common.dateTimeFormatter
import io.xxx.omni.osc.common.toJSONObject
import io.xxx.omni.osc.common.toLocalDateTime
import io.xxx.omni.osc.domain.*
import io.xxx.omni.osc.sdk.WphClient
import org.springframework.stereotype.Component
import java.time.LocalDateTime
import java.util.*

/**
 * 唯品会
 */
// https://vop.vip.com/doccenter/viewdoc/8
abstract class WphPorter : GenericPageDocumentPorter(), PlatformIdentity.WeiPinHui {

    protected abstract val method: String

    override val pageSize = 200

    override fun getResponse(context: JobContext, pageNo: Int, hasTotal: Boolean): JSONObject {
        val (store, startTime, endTime) = context
        val request = buildRequest(startTime, endTime, pageNo)
        val client = applicationContext.getBean(WphClient::class.java)
        val response = client.execute(store, method, request)
        if (response.getString("returnCode") != "0") {
            throwException(context, request, response)
        }
        return response
    }

    override fun getCount(context: JobContext, response: JSONObject): Int {
        return response.getJSONObject("result").getInteger("total")
    }

    protected abstract fun buildRequest(
        startTime: LocalDateTime,
        endTime: LocalDateTime,
        pageNo: Int
    ): Map<String, Any>
}

// 订单
// https://vop.vip.com/home#/api/method/detail/vipapis.marketplace.delivery.SovDeliveryService-1.0.0/getOrders
@Component
class WphTradePorter : WphPorter() {

    override val documentType = DocumentType.TRADE

    override val method = "getOrders"

    override fun buildDocuments(context: JobContext, response: JSONObject): List<Document> {
        return response
            .getJSONObject("result")
            .getJSONArray("orders")
            .map {
                val value = it.toJSONObject()
                val sn = value.getString("order_id")
                val status = value.getString("status")
                val modified = value.getString("last_update_time").toLocalDateTime()
                Document(sn, status, modified, value)
            }
    }

    override fun buildRequest(startTime: LocalDateTime, endTime: LocalDateTime, pageNo: Int): Map<String, Any> {
        return TreeMap(
            mapOf(
                "request" to mapOf(
                    "query_start_time" to startTime.format(dateTimeFormatter),
                    "query_end_time" to endTime.format(dateTimeFormatter),
                    "page" to pageNo,
                    "limit" to pageSize,
                )
            )
        )
    }
}

// 退单
// https://vop.vip.com/home#/api/method/detail/vipapis.marketplace.delivery.SovDeliveryService-1.0.0/batchGetCancelInfo
@Component
class WphRefundPorter : WphPorter() {

    override val documentType = DocumentType.REFUND

    override val method = "batchGetCancelInfo"

    override fun getStartTime(store: Store, jobCheckpoint: JobCheckpoint): LocalDateTime {
        val minStartTime = LocalDateTime.now().minusMonths(2)
        val startTime = jobCheckpoint.endTime
        return if (startTime < minStartTime) minStartTime else startTime
    }

    override fun buildDocuments(context: JobContext, response: JSONObject): List<Document> {
        return response
            .getJSONObject("result")
            .getJSONArray("cancelInfos")
            .map {
                val value = it.toJSONObject()
                val sn = value.getString("apply_sn")
                val rsn = value.getString("order_id")
                val status = value.getString("audit_status")
                Document(sn, rsn, status, value)
            }
    }

    override fun isNew(newDocument: Document, oldDocument: Document): Boolean {
        val new = newDocument.data!!.toJSONObject()
        val old = oldDocument.data!!.toJSONObject()
        return old.getInteger("audit_status") != new.getInteger("audit_status")
    }

    override fun buildRequest(startTime: LocalDateTime, endTime: LocalDateTime, pageNo: Int): Map<String, Any> {
        return TreeMap(
            mapOf(
                "request" to mapOf(
                    "start_time" to startTime.format(dateTimeFormatter),
                    "end_time" to endTime.format(dateTimeFormatter),
                    "page" to pageNo,
                    "limit" to pageSize,
                )
            )
        )
    }
}